/*
 * MIT License
 *
 * Copyright (c) 2023-present, tangli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package tony.mybatis.datascope

import java.util.concurrent.Callable
import tony.mybatis.datascope.model.DataScopeValue
import tony.mybatis.datascope.model.ScopedColumn
import tony.mybatis.datascope.model.ScopedTable

/**
 * 数据权限操作类.
 * @author tangli
 * @date 2025/09/20 00:04
 */
public sealed interface IDataScope {
    /**
     * 替换 默认用户id列表
     * @param [userIdList] 用户 ID 列表
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:02
     */
    public fun <T : Collection<String>> userIdList(userIdList: T): IDataScope

    /**
     * 包括用户 ID
     * @param [userId] 用户 ID
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:01
     */
    public fun includeUserId(vararg userId: String): IDataScope

    /**
     * 包括用户 ID 列表
     * @param [userIdList] 用户 ID 列表
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:01
     */
    public fun <T : Collection<String>> includeUserIdList(userIdList: T): IDataScope

    /**
     * 替换 默认组织id列表
     * @param [orgIdList] 组织 ID 列表
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:03
     */
    public fun <T : Collection<String>> orgIdList(orgIdList: T): IDataScope

    /**
     * 包括 组织 ID
     * @param [orgId] 组织 ID
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:01
     */
    public fun includeOrgId(vararg orgId: String): IDataScope

    /**
     * 包括组织 ID 列表
     * @param [orgIdList] 组织 ID 列表
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:01
     */
    public fun <T : Collection<String>> includeOrgIdList(orgIdList: T): IDataScope

    /**
     * 去掉组织id列表
     *
     * @author tangli
     * @date 2025/09/20 01:01
     */
    public fun withOutOrgId(): IDataScope

    /**
     * 设置用户id列名称.
     * @param [userIdColumn] 用户 ID 列
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:12
     */
    public fun userIdColumn(userIdColumn: String): IDataScope

    /**
     * 设置组织id列名称.
     * @param [orgIdColumn] 组织 ID 列
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:06
     */
    public fun orgIdColumn(orgIdColumn: String): IDataScope

    /**
     * 替换要排除的表.
     * 默认实现会补充 配置文件内的表列表.
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/17 10:32
     */
    public fun <T : Collection<ScopedTable>> excludeTables(tables: T): IDataScope

    /**
     * 替换要排除的表名
     * 默认实现会补充 配置文件内的表列表.
     * @param [tableNames] 表名
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:13
     */
    public fun <T : Collection<String>> excludeTableNames(tableNames: T): IDataScope

    /**
     * 替换 加入要处理的表
     * @param [tables] 表
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:13
     */
    public fun <T : Collection<ScopedTable>> includeTables(tables: T): IDataScope

    /**
     * 替换 加入要处理的表名
     * @param [tableNames] 表名
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/17 10:32
     */
    public fun <T : Collection<String>> includeTableNames(tableNames: T): IDataScope

    /**
     * 自定义 [userIdColumn], [orgIdColumn].
     * 根据 [tony.mybatis.datascope.model.ScopedColumn.tableAlias] 匹配.
     * @param [scopedColumns] 作用域列
     * @return [IDataScope]
     * @author tangli
     * @date 2025/09/20 01:15
     */
    public fun <T : Collection<ScopedColumn>> scopedColumns(scopedColumns: T): IDataScope

    /**
     * 数据权限内 执行 mybatis-plus 数据库操作
     * @param [func] 回调内执行 mybatis-plus 数据库操作
     * @return [T]
     * @author tangli
     * @date 2025/09/18 16:28
     */
    public fun <T> call(func: Callable<T>): T

    /**
     * 使用自定义数据, 数据权限内 执行 mybatis-plus 数据库操作
     * @param [func] 回调内执行 mybatis-plus 数据库操作
     * @return [T]
     * @author tangli
     * @date 2025/09/18 16:28
     */
    public fun <T> call(
        dataScopeValue: DataScopeValue,
        func: Callable<T>,
    ): T

    /**
     * 数据权限内 执行 mybatis-plus 数据库操作
     * @param [func] 回调内执行 mybatis-plus 数据库操作
     * @author tangli
     * @date 2025/09/18 16:28
     */
    public fun run(func: Runnable)

    /**
     *
     * 使用自定义数据, 数据权限内 执行 mybatis-plus 数据库操作.
     * @param [func] 回调内执行 mybatis-plus 数据库操作
     * @author tangli
     * @date 2025/09/18 16:28
     */
    public fun run(
        dataScopeValue: DataScopeValue,
        func: Runnable,
    )
}
